package com.alinesno.cloud.gateway.core.dispather.mina.codec;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alinesno.cloud.gateway.core.dispather.mina.bean.BusinessServerBean;
import com.alinesno.cloud.gateway.core.dispather.mina.bean.MessageBean;

import io.netty.util.CharsetUtil;

/**
 * 
 * 该类是负责编码 RequestMessageBean 为一系列字节 <br/>
 * 转换的 key 和实际请求的 body 到字节数组 <br/>
 * 计算 body 大小 <br/>
 * 写幻数到 ByteBuf 字节 <br/>
 * 写 opCode 作为字节 <br/>
 * 写 key 长度z作为 short <br/>
 * 编写额外的长度作为字节 <br/>
 * 写数据类型,这总是0,因为目前不是在 Memcached,但可用于使用 后来的版本 <br/>
 * 为保留字节写为 short ,后面的 Memcached 版本可能使用 <br/>
 * 写 body 的大小作为 long <br/>
 * 写 opaque 作为 int <br/>
 * 写 cas 作为 long。这个是头文件的最后部分，在 body 的开始 <br/>
 * 编写额外的 flag 和到期时间为 int <br/>
 * 写 key <br/>
 * 这个请求完成后 写 body <br/>
 * 编码器 使用 Netty 的 ByteBuf 处理请求，编码 MemcachedRequest 成一套正确排序的字节。详细步骤为： 写幻数字节。 写
 * opcode 字节。 写 key 长度(2字节)。 写额外的长度(1字节)。 写数据类型(1字节)。 为保留字节写 null 字节(2字节)。 写
 * body 长度(4字节- 32位整数)。 写 opaque(4个字节,一个32位整数在响应中返回)。 写 CAS(8个字节)。 写 额外的(flag 和
 * 到期,4字节)= 8个字节 写 key 写 值
 * 
 * @author WeiXiaoJin
 * @since 2019年9月21日 下午8:57:14
 */
public class RequestMessageEncoder extends ProtocolEncoderAdapter { // 1

	private static final Logger log = LoggerFactory.getLogger(RequestMessageEncoder.class);

	@SuppressWarnings("unused")
	private BusinessServerBean server;

	public RequestMessageEncoder(BusinessServerBean server) {
		this.server = server;
	}

	/**
	 * 发出消息解码
	 */
	@Override
	public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {

		log.debug("message = {}", message);

		MessageBean msg = (MessageBean) message;
		log.debug("消息发出:{} , length:{} ,  data:{}", msg.getMagic(), String.format("%08d", msg.getData().length()) , msg.getData());

		byte[] magic = msg.getMagic().getBytes(CharsetUtil.UTF_8);
		byte[] body = msg.getData().getBytes(CharsetUtil.UTF_8);
		byte[] length = String.format("%08d", msg.getData().length()).getBytes(CharsetUtil.UTF_8);

		System.out.println("magic = " + magic.length);
		System.out.println("length = " + length.length);
		
		// 根据报文长度开辟空间
		IoBuffer buff = IoBuffer.allocate(msg.getData().length());

		// 设置为可自动扩展空间
		buff.setAutoExpand(true);

		buff.put(magic);
		buff.put(length);
		buff.put(body);

		buff.flip();

		// 将报文发送出去
		out.write(buff);

		// session.closeOnFlush();
	}
}